package com.cff.mina.skt;

import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolEncoderAdapter;
import org.apache.mina.filter.codec.ProtocolEncoderOutput;

import com.cff.util.Logger;

public class MsgResponseEncoder extends ProtocolEncoderAdapter {
	
	private final int msgLength;   //报文长度位
	
	private Logger LOGGER = new Logger();

	public MsgResponseEncoder(int msgLength) {
		this.msgLength = msgLength;
	}

	public void encode(IoSession session, Object message,
			ProtocolEncoderOutput out) throws Exception {
		byte[] bb = (byte[]) message;
		IoBuffer buffer = IoBuffer.allocate(bb.length + msgLength);
		buffer.put(this.getLength(bb.length));
		buffer.put(bb);
		buffer.flip();
		out.write(buffer);
	}

	public byte[] getLength(int length) throws Exception{
		 byte[] headData = new byte[msgLength];
		 System.arraycopy(toHex2Len(length), 0, headData, 0, msgLength);
		 return headData;
	}
	
	public static byte[] toHex2Len(int i) {
		byte[] buffer = new byte[2];
		byte[] b = hex2byte(Integer.toHexString(i));
		if (b.length < 2) {
			buffer[0] = 0x00;
			buffer[1] = b[0];
		} else {
			System.arraycopy(b, 0, buffer, 0, 2);
		}
		return buffer;
	}
	
	public static byte[] hex2byte (String s) {
        if (s.length() % 2 == 0) {
            return hex2byte (s.getBytes(), 0, s.length() >> 1);
        } else {
        	// Padding left zero to make it even size #Bug raised by tommy
        	return hex2byte("0"+s);
        }
    }
	
	/**
     * @param   b       source byte array
     * @param   offset  starting offset
     * @param   len     number of bytes in destination (processes len*2)
     * @return  byte[len]
     */
    public static byte[] hex2byte (byte[] b, int offset, int len) {
        byte[] d = new byte[len];
        for (int i=0; i<len*2; i++) {
            int shift = i%2 == 1 ? 0 : 4;
            d[i>>1] |= Character.digit((char) b[offset+i], 16) << shift;
        }
        return d;
    }
}
